package 集合;

import javax.swing.tree.TreeNode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Vector;
import java.util.concurrent.ConcurrentSkipListSet;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;

public class CollectionDemo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("1");
        list.add("2");
        list.add("3");

        ListIterator<String> listIterator = list.listIterator();
        while (listIterator.hasPrevious()){
            String previous = listIterator.previous();
            System.out.println("previous = " + previous);
        }
        System.out.println("------------");
        while (listIterator.hasNext()){
            String next = listIterator.next();
            if ("1".equals(next)) {
                listIterator.set("11");
            }
            if ("2".equals(next)) {
                listIterator.remove();
            }
            if ("3".equals(next)) {
                listIterator.add("4");
            }
            System.out.println("next = " + next);
        }
        System.out.println("====================");
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            String next = iterator.next();
            System.out.println("next = " + next);
        }
    }


    /**
     * 10000000
     * arrayList遍历耗时:50
     * linkedList遍历耗时:172
     */
    private static void extracted7() {
        int count = 10000000;
        List<String> arrayList = new ArrayList<>();
        List<String> linkedList = new LinkedList<>();
        for (int i = 0; i < count; i++) {
            arrayList.add("lxw" + i);
            linkedList.add("lxw" + i);
        }
        long startA = System.currentTimeMillis();
        for (String s : arrayList) {
        }
        long endA = System.currentTimeMillis();
        for (String s : linkedList) {
        }
        long endL = System.currentTimeMillis();
        System.out.println("arrayList通过新循环遍历耗时:" + (endA - startA));
        System.out.println("linkedList通过新循环遍历耗时:" + (endL - endA));
    }

    /**
     * arrayList 通过for循环 遍历耗时:3
     * linkedList 通过for循环 遍历耗时:4
     * arrayList 通过fori循环遍历耗时:3
     * linkedList 通过fori循环遍历耗时:29011
     */
    private static void extracted8() {
        int count = 100000;
        List<String> arrayList = new ArrayList<>();
        List<String> linkedList = new LinkedList<>();
        for (int i = 0; i < count; i++) {
            arrayList.add("lxw" + i);
            linkedList.add("lxw" + i);
        }
        long startAfor = System.currentTimeMillis();
        for (String s : arrayList) {

        }
        long endAfor = System.currentTimeMillis();

        for (String s : linkedList) {

        }

        long endLfor = System.currentTimeMillis();
        for (int i = 0; i < arrayList.size(); i++) {
            String s = arrayList.get(i);
        }
        long endAfori = System.currentTimeMillis();
        for (int i = 0; i < linkedList.size(); i++) {
            String s = linkedList.get(i);
        }
        long endLfori = System.currentTimeMillis();

        System.out.println("arrayList 通过for循环 遍历耗时:" + (endAfor - startAfor));
        System.out.println("linkedList 通过for循环 遍历耗时:" + (endLfor - endAfor));
        System.out.println("arrayList 通过fori循环遍历耗时:" + (endAfori - endLfor));
        System.out.println("linkedList 通过fori循环遍历耗时:" + (endLfori - endAfori));
    }

    /**
     * 当添加第13个元素时扩容
     */
    private static void extracted6() {
        HashMap<String, Object> map = new HashMap<>(1);
        map.put("1", 1);
        map.put("2", 2);
        map.put("3", 3);
        map.put("4", 4);
        map.put("5", 5);
        map.put("6", 6);
        map.put("7", 7);
        map.put("8", 8);
        map.put("9", 9);
        map.put("10", 10);
        map.put("11", 11);
        map.put("12", 12);
        map.put("13", 13);
    }

    /**
     * 现将节点添加到链表,在判断是否需要树化
     * 当链表长度大于8时触发树化
     */
    private static void extracted5() {
        HashMap<String, Object> map = new HashMap<>();
        map.put("AaAaAaAaAaAaAaAaAa", 1);
        map.put("AaAaAaAaAaAaAaAaBB", 2);
        map.put("AaAaAaAaAaAaAaBBAa", 3);
        map.put("AaAaAaAaAaAaAaBBBB", 4);
        map.put("AaAaAaAaAaAaBBAaAa", 5);
        map.put("AaAaAaAaAaAaBBAaBB", 6);
        map.put("AaAaAaAaAaAaBBBBAa", 7);
        map.put("AaAaAaAaAaAaBBBBBB", 8);

        map.put("AaAaAaAaAaBBAaAaAa", 9);
//        System.out.println(generateN(4));
    }


    private static String[] base = new String[]{"Aa", "BB"};

    /**
     *
     */
    public static List<String> generateN(int n) {
        if (n <= 0) return null;
        List<String> list = generateOne(null);
        for (int i = 1; i < n; ++i) {
            list = generateOne(list);
        }
        return list;
    }

    public static List<String> generateOne() {
        return generateOne(null);
    }

    public static List<String> generateOne(List<String> strList) {
        if ((null == strList) || (0 == strList.size())) {
            strList = new ArrayList<String>();
            for (int i = 0; i < base.length; ++i) {
                strList.add(base[i]);
            }
            return strList;
        }
        List<String> result = new ArrayList<String>();
        for (int i = 0; i < base.length; ++i) {
            for (String str : strList) {
                result.add(base[i] + str);
            }
        }
        return result;
    }


    private static void extracted4() {
        //        addFromHeaderTest4ArrayList(100000);
//        addFromHeaderTest4LinkedList(100000);
        // 从中间添加 ArrayList 快
        // ArrayList从集合中间位置新增元素花费的时间17
        // LinkedList从集合中间位置新增元素花费的时间27388
//        addFromMidTest4ArrayList(100000);
//        addFromMidTest4LinkedList(100000);
        // 添加到末尾 数组不扩容 ArrayList 略快,需要扩容的多 LinkedList略快
        addFromTailTest4ArrayList(100000);
        addFromTailTest4LinkedList(100000);
    }

    public static void addFromHeaderTest4ArrayList(int num) {
        ArrayList<String> list = new ArrayList<>(num);
        int i = 0;
        long timeStart = System.currentTimeMillis();
        while (i < num) {
            list.add(0, i + "沉默王二");
            i++;
        }
        long timeEnd = System.currentTimeMillis();
        System.out.println("ArrayList从集合头部位置新增元素花费的时间" + (timeEnd - timeStart));
    }

    public static void addFromHeaderTest4LinkedList(int num) {
        LinkedList<String> list = new LinkedList<String>();
        int i = 0;
        long timeStart = System.currentTimeMillis();
        while (i < num) {
            list.addFirst(i + "沉默王二");
            i++;
        }
        long timeEnd = System.currentTimeMillis();
        System.out.println("LinkedList从集合头部位置新增元素花费的时间" + (timeEnd - timeStart));
    }

    public static void addFromMidTest4LinkedList(int num) {
        LinkedList<String> list = new LinkedList<>();
        int i = 0;
        long timeStart = System.currentTimeMillis();
        while (i < num) {
            int temp = list.size();
            list.add(temp / 2, i + "沉默王二");
            i++;
        }
        long timeEnd = System.currentTimeMillis();
        System.out.println("LinkedList从集合中间位置新增元素花费的时间" + (timeEnd - timeStart));
    }

    public static void addFromMidTest4ArrayList(int num) {
        ArrayList<String> list = new ArrayList<>(num);
        int i = 0;
        long timeStart = System.currentTimeMillis();
        while (i < num) {
            int temp = list.size();
            list.add(temp / 2 + "沉默王二");
            i++;
        }
        long timeEnd = System.currentTimeMillis();
        System.out.println("ArrayList从集合中间位置新增元素花费的时间" + (timeEnd - timeStart));
    }

    public static void addFromTailTest4ArrayList(int num) {
        ArrayList<String> list = new ArrayList<>(num);
        int i = 0;
        long timeStart = System.currentTimeMillis();
        while (i < num) {
            list.add(i + "沉默王二");
            i++;
        }
        long timeEnd = System.currentTimeMillis();
        System.out.println("ArrayList从集合尾部位置新增元素花费的时间" + (timeEnd - timeStart));
    }

    public static void addFromTailTest4LinkedList(int num) {
        LinkedList<String> list = new LinkedList<>();
        int i = 0;
        long timeStart = System.currentTimeMillis();
        while (i < num) {
            list.add(i + "沉默王二");
            i++;
        }
        long timeEnd = System.currentTimeMillis();
        System.out.println("LinkedList从集合尾部位置新增元素花费的时间" + (timeEnd - timeStart));
    }

    private static void extracted3() {
        LinkedList<String> list = new LinkedList<>();
        // 扩容 默认容量 10
        list.add("1");
        // index >= 0 && index <= size
        list.add(0, "1");
    }

    private static void extracted2() {
        ArrayList<String> list = new ArrayList<>();
        list.add(0, "1");
    }

    private static void extracted1() {
        ArrayList<String> list = new ArrayList<>();
        // 扩容 默认容量 10
        list.add("1");
        list.add("2");
        list.add("2");
        list.add("2");
        list.add("2");
        list.add("2");
        list.add("2");
        list.add("2");
        list.add("2");
        list.add("2");
        // 扩容 10+10>>1 = 15
        list.add("2");
        list.add("2");
        list.add("2");
        list.add("2");
        list.add("2");
        // 扩容 15+15>>1=22 1.5倍向下取整
        list.add("1");
    }

    private static void extracted() {
        List<String> list = null;
        list = new ArrayList<>();
        list.add("1");
        list.add(0, "1");
        list = new LinkedList<>();
        list = new Vector<>();
        list = new CopyOnWriteArrayList<>();
        list = new Stack<>();


        Set<Object> set = null;
        set = new HashSet<>();
        set = new LinkedHashSet<>();
        set = new TreeSet<>();
        set = new ConcurrentSkipListSet<>();
        set = new CopyOnWriteArraySet();
        // set = new EnumSet<>();

        Map<String, Object> map = null;
        map = new HashMap<>();
        map = new LinkedHashMap<>();
        map = new Hashtable<>();
        map = new TreeMap<>();
    }
}




